﻿namespace EveKillboard.Core
{
    using System;
    using System.Globalization;
    using System.Linq;
    using System.Text;
    using Services;
using EveKillboard.Core.Interfaces;

    public static class CoreExtensions
    {
        public static double ToUnixDateTime(this DateTime dateTime)
        {
            return Math.Round(dateTime.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds, 0);
        }

        public static bool CanGetHashKey(this IFeedKillmail killmail)
        {
            if(killmail == null)throw new ArgumentNullException("killmail");

            return !string.IsNullOrEmpty(killmail.VictimName) &&
                   !string.IsNullOrEmpty(killmail.VictimShipName) &&
                   !string.IsNullOrEmpty(killmail.VictimCorporationName) &&
                   !string.IsNullOrEmpty(killmail.VictimFactionName) &&
                   !string.IsNullOrEmpty(killmail.SystemName) &&
                   killmail.DamageReceived >= 0;
        }

        public static long GetHashKey(this IFeedKillmail killmail)
        {
            if (killmail == null ||!killmail.CanGetHashKey()) 
                throw new ArgumentNullException("killmail");

            var sb = new StringBuilder();
            sb.Append(killmail.Date.ToString("yyyyMMddhhmmss", CultureInfo.InvariantCulture))
                .Append(killmail.VictimName)
                .Append(killmail.VictimCorporationName.Replace("None", null).Replace("Unknown", null).Trim())
                .Append(string.IsNullOrEmpty(killmail.VictimAllianceName) ? null : killmail.VictimAllianceName.Replace("None", null).Replace("Unknown", null).Trim())
                .Append(string.IsNullOrEmpty(killmail.VictimFactionName) ? null : killmail.VictimFactionName.Replace("None", null).Replace("Unknown", null).Trim())
                .Append(killmail.VictimShipName)
                .Append(killmail.SystemName)
                .Append(killmail.DamageReceived);

            var hash = System.Security.Cryptography.SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(sb.ToString()));
            return BitConverter.ToInt64(hash, 0);
        }

        public static string ToTextFormat(this Killmail killmail)
        {
            var sb = new StringBuilder();

            sb.Append(string.Format("{0:yyyy.MM.dd} {1}",killmail.Date,killmail.Date.TimeOfDay));
            sb.AppendLine();

            if (killmail.Destroyed.Group.CategoryId == 6) // Ship
                sb.AppendFormat(CultureInfo.InvariantCulture, "Victim: {0}\r\n", killmail.Character.Name);

            sb.AppendFormat(CultureInfo.InvariantCulture, "Corp: {0}\r\n", killmail.Corporation == null ? "None" : killmail.Corporation.Name);
            sb.AppendFormat(CultureInfo.InvariantCulture, "Alliance: {0}\r\n", killmail.Alliance == null ? "None" : killmail.Alliance.Name);
            sb.AppendFormat(CultureInfo.InvariantCulture, "Faction: {0}\r\n", killmail.Faction == null ? "None" : killmail.Faction.Name);
            sb.AppendFormat(CultureInfo.InvariantCulture, "Destroyed: {0}\r\n", killmail.Destroyed.Name);

            if (killmail.Destroyed.Group.CategoryId == 23) // Structure
                sb.AppendFormat(CultureInfo.InvariantCulture, "Moon: {0}\r\n", "Unknown");

            sb.AppendFormat(CultureInfo.InvariantCulture, "System: {0}\r\n", killmail.Location.System);
            sb.AppendFormat(CultureInfo.InvariantCulture, "Security: {0}\r\n", killmail.Location.Security);
            sb.AppendFormat(CultureInfo.InvariantCulture, "Damage Taken: {0}\r\n", killmail.Damage);
            sb.AppendLine();
            sb.AppendLine("Involved parties:\r\n");

            foreach (var involved in killmail.Involved)
            {
                if (involved.Character.IsNpc.GetValueOrDefault(false) || ((involved.Ship != null && involved.Ship.Group.CategoryId != 6) || (involved.Ship == null && involved.Weapon != null && involved.Weapon.Group.CategoryId == 11 /* Sentry gun */ )))
                {
                    sb.AppendFormat(CultureInfo.InvariantCulture, "Name: {0} / {1}{2}\r\n", involved.Ship == null ? involved.Weapon == null ? "Unknown" : involved.Weapon.Name : involved.Ship.Name, involved.Corporation == null ? "Unknown" : involved.Corporation.Name, involved.IsFinalBlow ? " (laid the final blow)" : null);
                    sb.AppendFormat(CultureInfo.InvariantCulture, "Damage Done: {0}\r\n", involved.Damage);
                }
                else
                {
                    sb.AppendFormat(CultureInfo.InvariantCulture, "Name: {0}{1}\r\n", involved.Character.Name, involved.IsFinalBlow ? " (laid the final blow)" : null);
                    sb.AppendFormat(CultureInfo.InvariantCulture, "Security: {0:#0.0}\r\n", involved.Security);
                    sb.AppendFormat(CultureInfo.InvariantCulture, "Corp: {0}\r\n", involved.Corporation == null ? "None" : involved.Corporation.Name);
                    sb.AppendFormat(CultureInfo.InvariantCulture, "Alliance: {0}\r\n", involved.Alliance == null ? "None" : involved.Alliance.Name);
                    sb.AppendFormat(CultureInfo.InvariantCulture, "Faction: {0}\r\n", involved.Faction == null ? "None" : involved.Faction.Name);
                    sb.AppendFormat(CultureInfo.InvariantCulture, "Ship: {0}\r\n", involved.Ship == null ? "Unknown" : involved.Ship.Name);
                    sb.AppendFormat(CultureInfo.InvariantCulture, "Weapon: {0}\r\n", involved.Weapon == null ? "Unknown" : involved.Weapon.Name);
                    sb.AppendFormat(CultureInfo.InvariantCulture, "Damage Done: {0}\r\n", involved.Damage);
                }

                sb.AppendLine();
            }

            sb.AppendLine();
            if (killmail.Items.Any(i => i.IsDestroyed))
            {
                sb.AppendFormat("Destroyed items:\r\n");
                sb.AppendLine();
                foreach (var item in killmail.Items.Where(i => i.IsDestroyed))
                {
                    sb.AppendLine(item.ToString());
                }
            }

            sb.AppendLine();
            if (killmail.Items.Any(i => i.IsDropped))
            {
                sb.AppendFormat("Dropped items:\r\n");
                sb.AppendLine();
                foreach (var item in killmail.Items.Where(i => i.IsDropped))
                {
                    sb.AppendLine(item.ToString());
                }
            }

            return sb.ToString();
        }

        
        public static void TraceEvent(this System.Diagnostics.TraceSource traceSource, System.Diagnostics.TraceEventType eventType, string format, params object[] args)
        {
            if (traceSource != null && traceSource.Switch.ShouldTrace(eventType))
                if(args ==null)
                    traceSource.TraceEvent(eventType,0,format);
                else 
                    traceSource.TraceEvent(eventType,0,format,args);
        }

        public static void TraceEvent(this ITraceSource traceSource, System.Diagnostics.TraceEventType eventType, string format, params object[] args)
        {
            traceSource.Trace.TraceEvent(eventType,format,args);
        }
    }
}